home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / advanced97 / multiaccumaa.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  10.7 KB  |  437 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #ifdef _WIN32
  5. #include <windows.h>
  6. #define sleep(x) Sleep(1000*x)
  7. #else
  8. #include <unistd.h>
  9. #endif
  10.  
  11. #include <GL/glut.h>
  12.  
  13. const GLdouble FRUSTDIM = 100.f;
  14. int win_width = 256;
  15. int win_height = 256;
  16. int show_results = GL_TRUE;
  17. int object_offset, font_offset;
  18.  
  19. enum {SPHERE, CONE};
  20.  
  21. /*{0x00, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x03, 0x03},*/
  22. GLubyte rasters[][13] = {
  23. {0x00, 0x00, 0x3c, 0x66, 0xc3, 0xe3, 0xf3, 0xdb, 0xcf, 0xc7, 0xc3, 0x66, 0x3c},
  24. {0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x38, 0x18},
  25. {0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0xe7, 0x7e},
  26. {0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0x07, 0x03, 0x03, 0xe7, 0x7e},
  27. {0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xff, 0xcc, 0x6c, 0x3c, 0x1c, 0x0c},
  28. {0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xff},
  29. {0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},
  30. {0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x03, 0x03, 0xff},
  31. {0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e},
  32. {0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x03, 0x7f, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e},
  33. };
  34.  
  35. GLfloat mults[] = {1., 1./2., 2./3., 3./4., 4./5., 5./6., 6./7., 7./8., 8./9., 9./10.};
  36.  
  37.  
  38. /*
  39. ** Create a single component texture map
  40. */
  41.  
  42. void make_font(void)
  43. {
  44.    GLuint i;
  45.    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  46.  
  47.    font_offset = glGenLists (10);
  48.    for (i = 0; i < 10; i++) {
  49.       glNewList(i+font_offset, GL_COMPILE);
  50.       glBitmap(8, 13, 0.0, 2.0, 10.0, 0.0, rasters[i]);
  51.       glEndList();
  52.    }
  53. }
  54.  
  55. GLfloat *make_texture(int maxs, int maxt)
  56. {
  57.     int s, t;
  58.     static GLfloat *texture;
  59.  
  60.     texture = (GLfloat *)malloc(maxs * maxt * sizeof(GLfloat));
  61.     for(t = 0; t < maxt; t++) {
  62.     for(s = 0; s < maxs; s++) {
  63.         texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1);
  64.     }
  65.     }
  66.     return texture;
  67. }
  68.  
  69. void print_frame_number(GLuint frame)
  70. {
  71.     GLuint f1, f2;
  72.  
  73.     glPushAttrib( GL_ENABLE_BIT | GL_CURRENT_BIT);
  74.  
  75.     glMatrixMode(GL_PROJECTION);
  76.     glPushMatrix();
  77.     glLoadIdentity();
  78.     glOrtho (0.0, win_width, 0.0, win_height, -1.0, 1.0);
  79.     glMatrixMode(GL_MODELVIEW);
  80.     glPushMatrix();
  81.     glLoadIdentity();
  82.  
  83.     glDisable(GL_DEPTH_TEST);
  84.     glDisable(GL_LIGHTING);
  85.     glDisable(GL_TEXTURE_2D);
  86.  
  87.     glColor3f(1.0, 0.0, 0.0);
  88.  
  89.     f1 = frame/10;
  90.     if (f1 > 0) {
  91.         glRasterPos2i(50, win_height - 50);
  92.         glCallList(font_offset + f1);
  93.     }
  94.     else
  95.         glRasterPos2i(60, win_height - 50);
  96.     f2 = frame - f1*10;
  97.     glCallList(font_offset + f2);
  98.  
  99.     glPopMatrix();
  100.     glMatrixMode(GL_PROJECTION);
  101.     glPopMatrix();
  102.     glPopAttrib();
  103. }
  104.  
  105. void
  106. render(void)
  107. {
  108.     /* material properties for objects in scene */
  109.     static GLfloat wall_mat[] = {1.f, 1.f, 1.f, 1.f};
  110.  
  111.     glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
  112.  
  113.     /*
  114.     ** Note: wall verticies are ordered so they are all front facing
  115.     ** this lets me do back face culling to speed things up.
  116.     */
  117.  
  118.     glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat);
  119.  
  120.     /* floor */
  121.     /* make the floor textured */
  122.     glEnable(GL_TEXTURE_2D);
  123.  
  124.     /*
  125.     ** Since we want to turn texturing on for floor only, we have to
  126.     ** make floor a separate glBegin()/glEnd() sequence. You can't
  127.     ** turn texturing on and off between begin and end calls
  128.     */
  129.     glBegin(GL_QUADS);
  130.     glNormal3f(0.f, 1.f, 0.f);
  131.     glTexCoord2i(0, 0);
  132.     glVertex3f(-100.f, -100.f, -320.f);
  133.     glTexCoord2i(1, 0);
  134.     glVertex3f( 100.f, -100.f, -320.f);
  135.     glTexCoord2i(1, 1);
  136.     glVertex3f( 100.f, -100.f, -520.f);
  137.     glTexCoord2i(0, 1);
  138.     glVertex3f(-100.f, -100.f, -520.f);
  139.     glEnd();
  140.  
  141.     glDisable(GL_TEXTURE_2D);
  142.  
  143.     /* walls */
  144.  
  145.     glBegin(GL_QUADS);
  146.     /* left wall */
  147.     glNormal3f(1.f, 0.f, 0.f);
  148.     glVertex3f(-100.f, -100.f, -320.f);
  149.     glVertex3f(-100.f, -100.f, -520.f);
  150.     glVertex3f(-100.f,  100.f, -520.f);
  151.     glVertex3f(-100.f,  100.f, -320.f);
  152.  
  153.     /* right wall */
  154.     glNormal3f(-1.f, 0.f, 0.f);
  155.     glVertex3f( 100.f, -100.f, -320.f);
  156.     glVertex3f( 100.f,  100.f, -320.f);
  157.     glVertex3f( 100.f,  100.f, -520.f);
  158.     glVertex3f( 100.f, -100.f, -520.f);
  159.  
  160.     /* ceiling */
  161.     glNormal3f(0.f, -1.f, 0.f);
  162.     glVertex3f(-100.f,  100.f, -320.f);
  163.     glVertex3f(-100.f,  100.f, -520.f);
  164.     glVertex3f( 100.f,  100.f, -520.f);
  165.     glVertex3f( 100.f,  100.f, -320.f);
  166.  
  167.     /* back wall */
  168.     glNormal3f(0.f, 0.f, 1.f);
  169.     glVertex3f(-100.f, -100.f, -520.f);
  170.     glVertex3f( 100.f, -100.f, -520.f);
  171.     glVertex3f( 100.f,  100.f, -520.f);
  172.     glVertex3f(-100.f,  100.f, -520.f);
  173.     glEnd();
  174.  
  175.  
  176.     glPushMatrix();
  177.     glTranslatef(-80.f, -60.f, -420.f);
  178.     glCallList(object_offset + SPHERE);
  179.     glPopMatrix();
  180.  
  181.  
  182.     glPushMatrix();
  183.     glTranslatef(-20.f, -80.f, -500.f);
  184.     glCallList(object_offset + CONE);
  185.     glPopMatrix();
  186.  
  187.     if(glGetError()) /* to catch programming errors; should never happen */
  188.        printf("Oops! I screwed up my OpenGL calls somewhere\n");
  189.  
  190.     glFlush(); /* high end machines may need this */
  191. }
  192.  
  193. /* compute scale factor for window->object space transform */
  194. /* could use gluUnProject(), but probably too much trouble */
  195. void
  196. computescale(GLfloat *sx, GLfloat *sy)
  197. {
  198.   enum {XORG, YORG, WID, HT};
  199.   GLint viewport[4];
  200.   glGetIntegerv(GL_VIEWPORT, viewport);
  201.  
  202.   *sx = 2 * FRUSTDIM/viewport[WID];
  203.   *sy = 2 * FRUSTDIM/viewport[WID];
  204. }
  205.  
  206. enum {NONE, AA, AA_NEW};
  207.  
  208. int rendermode = NONE;
  209.  
  210. void
  211. menu(int selection)
  212. {
  213.   rendermode = selection;
  214.   glutPostRedisplay();
  215. }
  216.  
  217.  
  218.  
  219. /* Called when window needs to be redrawn */
  220. void redraw(void)
  221. {
  222.     GLfloat invx, invy;
  223.     GLfloat scale, dx, dy;
  224.     int i, j;
  225.     int min, max;
  226.     int count, nframes;
  227.  
  228.     switch(rendermode) {
  229.     case NONE:
  230.       glMatrixMode(GL_PROJECTION);
  231.       glLoadIdentity();
  232.       glFrustum(-FRUSTDIM, FRUSTDIM, -FRUSTDIM,    FRUSTDIM, 320., 640.); 
  233.       glMatrixMode(GL_MODELVIEW);
  234.       render();
  235.       glutSwapBuffers();
  236.       break;
  237.     case AA:
  238.       min = -1;
  239.       max = -min + 1;
  240.       count = -2 * min + 1;
  241.       count *= count;
  242.       /* uniform scaling, less than one pixel wide */
  243.       scale = -.9f/min;
  244.  
  245.       computescale(&invx, &invy);
  246.  
  247.       glClear(GL_ACCUM_BUFFER_BIT);
  248.  
  249.       for(j = min, nframes = 1; j < max; j++) {
  250.     for(i = min; i < max; i++, nframes++) {
  251.       dx = invx * scale * i;
  252.       dy = invy * scale * j;
  253.       glMatrixMode(GL_PROJECTION);
  254.       glLoadIdentity();
  255.       glFrustum(-FRUSTDIM + dx, 
  256.             FRUSTDIM + dy, 
  257.             -FRUSTDIM + dx, 
  258.             FRUSTDIM + dy, 
  259.             320., 640.); 
  260.       glMatrixMode(GL_MODELVIEW);
  261.       render();
  262.       glAccum(GL_ACCUM, 1.f/count);
  263.  
  264.           if (show_results) {
  265.         if (nframes == 1) {
  266.         glutSwapBuffers();
  267.             glDrawBuffer(GL_FRONT);
  268.         } else if (nframes == 2) {
  269.             glDrawBuffer(GL_FRONT);
  270.                 glAccum(GL_RETURN, 3.99);
  271.             } else {
  272.             glDrawBuffer(GL_FRONT);
  273.                 glAccum(GL_RETURN, (GLfloat)count/(GLfloat)nframes);
  274.         }
  275.         print_frame_number(nframes);
  276.             glFlush();
  277.         printf("frame number %d\n",nframes);
  278.         glDrawBuffer(GL_BACK);
  279.         sleep(3);
  280.       }
  281.     }
  282.       }
  283.       if (!show_results) {
  284.      glAccum(GL_RETURN, 1.f);
  285.          glutSwapBuffers();
  286.       }
  287.       break;
  288.     case AA_NEW:
  289.       min = -2;
  290.       max = -min + 1;
  291.       count = -2 * min + 1;
  292.       count *= count;
  293.       /* uniform scaling, less than one pixel wide */
  294.       scale = -.9f/min;
  295.  
  296.       computescale(&invx, &invy);
  297.  
  298.       glClear(GL_ACCUM_BUFFER_BIT);
  299.  
  300.       for(j = min, nframes = 1; j < max; j++) {
  301.     for(i = min; i < max; i++, nframes++) {
  302.       dx = invx * scale * i;
  303.       dy = invy * scale * j;
  304.       glMatrixMode(GL_PROJECTION);
  305.       glLoadIdentity();
  306.       glFrustum(-FRUSTDIM + dx, 
  307.             FRUSTDIM + dy, 
  308.             -FRUSTDIM + dx, 
  309.             FRUSTDIM + dy, 
  310.             320., 640.); 
  311.       glMatrixMode(GL_MODELVIEW);
  312.       render();
  313.        if (nframes == 1)
  314.           glAccum(GL_ACCUM, 1.);
  315.        else
  316.           glAccum(GL_ACCUM, .5);
  317.  
  318.           if (show_results) {
  319.           glDrawBuffer(GL_FRONT);
  320.               glAccum(GL_RETURN, 1.);
  321.           print_frame_number(nframes);
  322.               glFlush();
  323.           printf("frame number %d\n",nframes);
  324.           glDrawBuffer(GL_BACK);
  325.           sleep(3);
  326.       }
  327.  
  328.       if (nframes < count) {
  329.           glAccum(GL_RETURN, 1.);
  330.           glAccum(GL_LOAD, .5);
  331.           }
  332.  
  333.     }
  334.       }
  335.       if (!show_results) {
  336.      glAccum(GL_RETURN, 1.f);
  337.          glutSwapBuffers();
  338.       }
  339.       break;
  340.     }
  341.  
  342. }
  343.  
  344. void reshape(int w, int h)
  345. {
  346.     if (w < h) {
  347.        win_height = win_width = w;
  348.     } else {
  349.        win_height = win_width = h;
  350.     }
  351.     glViewport(0, 0, win_width, win_height);
  352. }
  353.  
  354. /* ARGSUSED1 */
  355. void key(unsigned char key, int x, int y)
  356. {
  357.     if(key == '\033')
  358.     exit(0);
  359. }
  360.  
  361.  
  362. const int TEXDIM = 256;
  363. /* Parse arguments, and set up interface between OpenGL and window system */
  364. main(int argc, char *argv[])
  365. {
  366.     GLfloat *tex;
  367.     static GLfloat lightpos[] = {50.f, 50.f, -320.f, 1.f};
  368.     static GLfloat sphere_mat[] = {1.f, .5f, 0.f, 1.f};
  369.     static GLfloat cone_mat[] = {0.f, .5f, 1.f, 1.f};
  370.     GLUquadricObj *sphere, *cone, *base;
  371.  
  372.     glutInit(&argc, argv);
  373.     glutInitWindowSize(win_width, win_height);
  374.     glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_ACCUM|GLUT_DOUBLE);
  375.     (void)glutCreateWindow("Accum antialias");
  376.     glutDisplayFunc(redraw);
  377.     glutKeyboardFunc(key);
  378.     glutReshapeFunc(reshape);
  379.  
  380.     glutCreateMenu(menu);
  381.     glutAddMenuEntry("Aliased View", NONE);
  382.     glutAddMenuEntry("AntiAliased View", AA);
  383.     glutAttachMenu(GLUT_RIGHT_BUTTON);
  384.  
  385.     make_font();
  386.  
  387.     /* draw a perspective scene */
  388.     glMatrixMode(GL_PROJECTION);
  389.     glFrustum(-FRUSTDIM, FRUSTDIM, -FRUSTDIM, FRUSTDIM, 320., 640.); 
  390.     glMatrixMode(GL_MODELVIEW);
  391.  
  392.     /* turn on features */
  393.     glEnable(GL_DEPTH_TEST);
  394.     glEnable(GL_LIGHTING);
  395.     glEnable(GL_LIGHT0);
  396.  
  397.     /* place light 0 in the right place */
  398.     glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  399.  
  400.     /* remove back faces to speed things up */
  401.     glCullFace(GL_BACK);
  402.  
  403.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  404.  
  405.     object_offset = glGenLists(2);
  406.     glNewList(object_offset + SPHERE, GL_COMPILE);
  407.     /* make display lists for sphere and cone; for efficiency */
  408.     sphere = gluNewQuadric();
  409.     glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat);
  410.     gluSphere(sphere, 20.f, 20, 20);
  411.     gluDeleteQuadric(sphere);
  412.     glEndList();
  413.  
  414.     glNewList(object_offset + CONE, GL_COMPILE);
  415.     cone = gluNewQuadric();
  416.     base = gluNewQuadric();
  417.     glRotatef(-90.f, 1.f, 0.f, 0.f);
  418.     glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat);
  419.     gluDisk(base, 0., 20., 20, 1);
  420.     gluCylinder(cone, 20., 0., 60., 20, 20);
  421.     gluDeleteQuadric(cone);
  422.     gluDeleteQuadric(base);
  423.     glEndList();
  424.  
  425.     /* load pattern for current 2d texture */
  426.     tex = make_texture(TEXDIM, TEXDIM);
  427.     glTexImage2D(GL_TEXTURE_2D, 0, 1, TEXDIM, TEXDIM, 0, GL_RED, GL_FLOAT, tex);
  428.     free(tex);
  429.  
  430.     glReadBuffer(GL_BACK); /* input to accum buffer */
  431.  
  432.     glutMainLoop();
  433.  
  434.     return 0;
  435. }
  436.  
  437.